package com.fss.common.dao;
import com.fssDataModels.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class CommonDaoImpl implements CommonDao{
	private SessionFactory _sessions;
	
	public CommonDaoImpl()
	{
		// Create the SessionFactory from hibernate.cfg.xml
		_sessions = new Configuration()				
				.configure()
				.buildSessionFactory();
	}
	//function: getActivities
	//		(get the most recently uploaded activities by userType)
	//input:
	//		-numOfResult: the maximum number of activities to be returned
	//		-userType(0->admin,not 0->normal user):only activities created by users of "userType" will be returned
	//		-adminIds: the list contains three ids of predefined administrators (3 admins)
	public List getActivities(int numOfResult,Integer userType)
	{
		Session session = _sessions.openSession();

		Transaction tx = null;
		List result = null;
		try {
			tx = session.beginTransaction();
			String hql=null;
			Query query ;
			
			//get the ids of the predefined administrators
			String admin1Id="fss_admin1";
			String admin2Id="fss_admin2";
			String admin3Id="fss_admin3";
			
			if(userType==0)//get activities created by administrators
			{				
				hql=	"from TbActivity activity " +
							"where activity.tbUser.userId in (:admin1Id,:admin2Id,:admin3Id) "+
							"order by activity.createdTime desc ";//get the most recently uploaded activities
			}
			else//get activities created by normal users
			{
				hql=	"from TbActivity activity " +
						"where activity.tbUser.userId not in (:admin1Id,:admin2Id,:admin3Id) "+
						"order by activity.createdTime desc ";//get the most recently uploaded activities
			}
									
			query = session.createQuery(hql);
			query.setParameter("admin1Id", admin1Id);
			query.setParameter("admin2Id", admin2Id);
			query.setParameter("admin3Id", admin3Id);
			query.setMaxResults(numOfResult);
			
			if(!query.list().isEmpty())				
				result=query.list();
			
			tx.commit();
		}
		catch (HibernateException he) {
			if (tx!=null) tx.rollback();
			// do nothing else
		}
		finally {
			session.close();
		}
		return result;
	}
	
	/*function name: getExperiences
	 *function signature: public List getExperiences(TbExperienceType experienceType ,Date fromDate,Date toDate)
	 *task:
	 *  (fromDate==NULL --> get the experiences uploaded before toDate)
	 *  (experienceType== null --> return experiences of all types
	 */
	public List getExperiences(TbExperienceType experienceType ,Date fromDate,Date toDate)
	{
		Session session = _sessions.openSession();
		Transaction tx = null;
		List result = null;
		String hql;
		
		try {
			tx = session.beginTransaction();
			Query query;
			
			if(fromDate==null)
			{
				if(experienceType==null)
				{
					hql=	"from TbExperience experience " +
					"where experience.createdTime <= :toDate " +							
					"order by experience.createdTime desc ";//get the most recently uploaded activities
		
					query = session.createQuery(hql);				
					query.setParameter("toDate", toDate);					
				}
				else
				{
					hql=	"from TbExperience experience " +
								"where experience.createdTime <= :toDate " +
										" and experience.tbExperienceType = :experienceType "+
								"order by experience.createdTime desc ";//get the most recently uploaded activities
					
					query = session.createQuery(hql);				
					query.setParameter("toDate", toDate);
					query.setParameter("experienceType", experienceType);
				}
				
			}
			else
			{
				if(experienceType==null)
				{
					hql=	"from TbExperience experience " +
					"where experience.createdTime between :fromDate and :toDate "+					
					"order by experience.createdTime desc ";//get the most recently uploaded activities
					
					query = session.createQuery(hql);
					query.setParameter("fromDate", fromDate);
					query.setParameter("toDate", toDate);
					
				}
				else
				{
					hql=	"from TbExperience experience " +
					"where experience.createdTime between :fromDate and :toDate "+
							" and experience.tbExperienceType = :experienceType "+
					"order by experience.createdTime desc ";//get the most recently uploaded activities
					
					query = session.createQuery(hql);
					query.setParameter("fromDate", fromDate);
					query.setParameter("toDate", toDate);
					query.setParameter("experienceType", experienceType);
				}
				
			}
			
			
			if(!query.list().isEmpty())				
				result=query.list();
			
			tx.commit();
		}
		catch (HibernateException he) {
			if (tx!=null) tx.rollback();
			//do nothing else
		}
		finally {
			session.close();
		}
		
		
		return result;
	}
	
	public List getExperienceTypes()
	{
		Session session = _sessions.openSession();
		Transaction tx = null;
		List result = null;
		String hql;
		
		try {
			tx = session.beginTransaction();
			
			hql=	"from TbExperienceType";
									
			Query query = session.createQuery(hql);
			
			if(!query.list().isEmpty())				
				result=query.list();
			
			tx.commit();
		}
		catch (HibernateException he) {
			if (tx!=null) tx.rollback();
			//do nothing else
		}
		finally {
			session.close();
		}
		return result;
		
	}
	/*function name: getSecondHandItems
	 *function signature: public List getSecondHandItems(Date fromDate,Date toDate)
	 *task:
	 *  (fromDate==NULL --> get the secondhand items uploaded before toDate)
	 * 
	 */
	public List getSecondHandItems(Date fromDate,Date toDate)
	{
		Session session = _sessions.openSession();
		Transaction tx = null;
		List result = null;
		String hql;
		try {
			tx = session.beginTransaction();
			Query query;
			
			if(fromDate==null)
			{
				hql=	"from TbSecondhandItem item " +
							"where item.createdTime <= :toDate "+
							"order by item.createdTime desc ";//get the most recently uploaded activities
				query = session.createQuery(hql);				
				query.setParameter("toDate", toDate);
				
			}
			else
			{
				hql=	"from TbSecondhandItem item " +
				"where item.createdTime between :fromDate and :toDate "+
				"order by item.createdTime desc ";//get the most recently uploaded activities
			
				query = session.createQuery(hql);
				query.setParameter("fromDate", fromDate);
				query.setParameter("toDate", toDate);
			}
			
			if(!query.list().isEmpty())				
				result=query.list();
			
			tx.commit();
		}
		catch (HibernateException he) {
			if (tx!=null) tx.rollback();
			//do nothing else
		}
		finally {
			session.close();
		}
		return result;
	}
	
	/*function name: getUsers
	 *function signature: public List getUsers(Date fromDate,Date toDate)
	 *task:
	 *  (fromDate==NULL --> get users registered before toDate)
	 * 
	 */
	public List getUsers(Date fromDate,Date toDate)
	{
		Session session = _sessions.openSession();
		Transaction tx = null;
		List result = null;
		String hql;
		
		try {
			tx = session.beginTransaction();
			Query query;
			
			if(fromDate==null)
			{
				hql=	"from TbUser user " +
							"where user.createdTime <= :toDate "+
							"order by user.createdTime desc ";//get the most recently uploaded activities
				query = session.createQuery(hql);				
				query.setParameter("toDate", toDate);
				
			}
			else
			{
				hql=	"from TbUser user " +
						"where user.createdTime between :fromDate and :toDate "+
						"order by user.createdTime desc ";//get the most recently uploaded activities
				query = session.createQuery(hql);
				query.setParameter("fromDate", fromDate);
				query.setParameter("toDate", toDate);
				
			}						
			
			if(!query.list().isEmpty())				
				result=query.list();
			
			tx.commit();
		}
		catch (HibernateException he) {
			if (tx!=null) tx.rollback();
			//do nothing else
		}
		finally {
			session.close();
		}
		
		/*delete the 3 admin users from the list*/
	 
		for (int i = 0; i < result.size(); i++) {
		   TbUser user = (TbUser)result.get(i);
		   String userId = user.getUserId();
		   
		   System.out.println(userId);
		   
		   if("fss_admin1".equalsIgnoreCase(userId) || "fss_admin3".equalsIgnoreCase(userId) || "fss_admin2".equalsIgnoreCase(userId)){
			   result.remove(i);
			   i--;
			   System.out.println(userId);
		   }
		} 
		
		return result;
	}
	public List getCmsContents()
	{
		Session session = _sessions.openSession();
		Transaction tx = null;
		List result = null;
		try {
			tx = session.beginTransaction();
			String hql=	"from TbCmsContent";
									
			Query query = session.createQuery(hql);
			
			if(!query.list().isEmpty())				
				result=query.list();
			
			tx.commit();
		}
		catch (HibernateException he) {
			if (tx!=null) tx.rollback();
			//do nothing else
		}
		finally {
			session.close();
		}
		return result;
	}
	public int updateCmsContents(List cmsContents)
	{
		int result=1;
		//parse through the list of cmsContent and update one by one
		for (int i=0; i< cmsContents.size(); i++)
		{
			TbCmsContent cms=(TbCmsContent)cmsContents.get(i);
			Session session = _sessions.openSession();
			Transaction tx = null;
			try {
				tx = session.beginTransaction();
				session.update(cms);
				tx.commit();
			}
			catch (HibernateException he) {
				if (tx!=null) tx.rollback();
				result = 0;
			}
			finally {
				session.close();
			}
		}//end for
		return result;
	}

}
